<?php

class Monkake {
	// Store errors in $this->_errors, if $fatal == TRUE death occurs
	private $_Errors = array();
	public function Error($message, $fatal = false) {
		$this->_Errors[] = array(
			'message' => $message,
			'debug_backtrace' => debug_backtrace(),
			);

		if ( $fatal ) {
			echo Monkake::Get('fatal_error_message', 'An error occured while processing your request.');
			if ( Monkake::Get('debug') ) {
				echo '<pre>';
				var_dump($this->_Errors);
				echo '</pre>';
			}
			die();
		}
	} // Error()

	// URL intercepts
	public function GetIntercept($path) {
		$intercepts = Monkake::Get('url_intercepts', array(), FALSE);
		foreach ( $intercepts as $pattern => $handlers_view ) {
			if ( eregi($pattern, $path) ) {
				return $handlers_view;
			}
		}

		return NULL;
	}

	public function GetHandler($names, $m, $view) {
		if ( !is_array($names) ) $names = array($names);

		foreach ( $names as $name ) {
			$handler_path = Monkake::Get('handler_directory') . $name .  Monkake::Get('handler_append');

			if ( !(file_exists($handler_path)) || !(include_once($handler_path)) || !(class_exists($name . '_handler')) ) {
				$this->Error('Could not load handler');
			}
		}

		$parts = split('/', $name);
		$name = $parts[count($parts) - 1];
		eval('$obj = new ' . $name . '_handler($m, $view);');

		return $obj;
	}

	public function IncludeModel($name) {
		$path = Monkake::Get('models_directory', NULL, TRUE) . $name . '.model.php';
		$included_files = get_included_files();

		if ( !in_array($path, $included_files) ) {
			if ( (file_exists($path)) && (require_once($path)) && (class_exists($name)) ) {
			} else {
				return false;
			}
		}

		return true;
	}

	// STATIC
	public static function IncludeClass($name) {
		$override_path = Monkake::Get('class_override_directory') . $name . '.class.php';
		$path = Monkake::Get('class_directory', NULL, TRUE) . $name . '.class.php';
		$included_files = get_included_files();

		if ( !in_array($override_path, $included_files) && !in_array($path, $included_files) ) {
			if ( (file_exists($override_path)) && (require_once($override_path)) && (class_exists($name)) ) {
			} elseif ( (file_exists($path)) && (require_once($path)) && (class_exists($name)) ) {
			} else {
				return false;
			}
		}

		return true;
	}

	public static function GetObject($name) {
		if ( !self::IncludeClass($name) ) die('an error occured while trying to load the class file "' . $override_path . ', ' . $path . '"');

		if ( func_num_args() > 1 ) {
			$args = array();
			for ( $arg_count = 1; $arg_count < func_num_args(); $arg_count++ ) {
				$args[]  = func_get_arg($arg_count);
			}

			$arg_names = array();
			foreach ( $args as $key => $val ) {
				$arg_names[] = '$args[' . $key . ']';
			}
			eval('$obj = new ' . $name . '(' . implode(', ', $arg_names) . ');');
		} else {
			eval('$obj = new ' . $name . '();');
		}

		return $obj;
	}

	private static $_Config = array();
	// Get a value from $this->_config, if $required is passed as TRUE and value not defined, death occurs
	public static function Get($var_name, $default = NULL, $required = FALSE) {
		if ( isset(self::$_Config[$var_name]) ) {
			return self::$_Config[$var_name];
		} elseif ( !$required ) {
			return $default;
		} else {
			throw new RequiredConfigKeyNotSetException('Required configuration missing ' . $var_name);
		}
	} // Get()

	public static function Set($var_name, $var_value, $overwrite = TRUE) {
		if ( $overwrite ) {
			self::$_Config[$var_name] = $var_value;
		} else if ( !isset(self::$_Config[$var_name]) ) {
			self::$_Config[$var_name] = $var_value;
		}
	} // Set()
}

class RequiredConfigKeyNotSetException extends Exception { }